/**
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

// Example of reading/writing an external serial flash using the PL022 SPI interface

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/binary_info.h"
#include "hardware/spi.h"

#include "wizchip_conf.h"
#include "bsp_spi.h"
#include "dhcp.h"

#define ETHERNET_BUF_MAX_SIZE (1024 * 2)
#define SOCKET_DHCP 0
#define DHCP_RETRY_COUNT 5

wiz_NetInfo net_info = {
    .mac = {0x00, 0x08, 0xdc, 0x16, 0xed, 0x2e}, // Define MAC variables
    .ip = {192, 168, 1, 10},                     // Define IP variables
    .sn = {255, 255, 255, 0},                    // Define subnet variables
    .gw = {192, 168, 1, 1},                      // Define gateway variables
    .dns = {8, 8, 8, 8},                         // Define DNS  variables
    .dhcp = NETINFO_DHCP};                       // Define the DNCP mode
static uint8_t dhcp_get_ip_flag = 0;             // Define the DHCP acquisition flag
static uint8_t ethernet_buf[ETHERNET_BUF_MAX_SIZE] = {
    0,
};

/*
    @brief Callback processing after triggering the timer.
    @param Timer struct.
    @return True.
 */
bool repeating_timer_callback(struct repeating_timer *t);

int main()
{
    wiz_NetInfo get_info;
    int dhcp_state = 0;
    int count = 0;
    struct repeating_timer timer; // Define the timer structure

    /*mcu init*/
    stdio_init_all();     // Initialize the main control peripheral
    wizchip_initialize(); // spi initialization

    /*wiznet chip init*/
    wizchip_setnetinfo(&net_info); // Write configuration information

    /*dhcp init*/
    add_repeating_timer_ms(1000, repeating_timer_callback, NULL, &timer); // Add  DHCP 1s Tick Timer handler
    DHCP_init(SOCKET_DHCP, ethernet_buf); // DHCP initialization
    printf("wiznet chip dhcp example start.\r\n");

    while (true)
    {
        dhcp_state = DHCP_run(); // Do the DHCP client

        switch (dhcp_state)
        {
        case DHCP_IP_LEASED: // DHCP resolves the domain name successfully
            if (dhcp_get_ip_flag == 0)
            {
                dhcp_get_ip_flag = 1;

                getSHAR(get_info.mac);
                getIPfromDHCP(get_info.ip);
                getGWfromDHCP(get_info.gw);
                getSNfromDHCP(get_info.sn);
                getDNSfromDHCP(get_info.dns);
                get_info.dhcp = NETINFO_DHCP;

                /* Network initialize */
                network_initialize(get_info); // apply from DHCP

                print_network_information(&get_info); // Read back the configuration information and print it
                printf(" DHCP leased time : %ld seconds\n", getDHCPLeasetime());
            }
            break;
        case DHCP_FAILED:
            count++;
            if (count <= DHCP_RETRY_COUNT) // If the number of times is less than or equal to the maximum number of times, try again
            {
                printf(" DHCP timeout occurred and retry %d \r\n", count);
            }
            else if (count > DHCP_RETRY_COUNT) // If the number of times is greater than DHCP fails
            {
                printf(" DHCP failed \r\n");

                DHCP_stop(); // Stop processing DHCP protocol

                net_info.dhcp = NETINFO_STATIC;
                wizchip_setnetinfo(&net_info); // Write configuration information

                print_network_information(&get_info); // Read back the configuration information and print it
            }
        }
    }
}

bool repeating_timer_callback(struct repeating_timer *t)
{
    DHCP_time_handler(); // DHCP 1s Tick Timer handler
    return true;
}
